﻿using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using XS.Tunnel.Cad.SteelBracing.BusinessExtensions;
using XS.Tunnel.Cad.SteelBracing.Component.SteelShotcrete.UniversalBeamComponent;
using XS.Tunnel.Cad.SteelBracing.Infrastructure;
using XS.Tunnel.Cad.SteelBracing.Infrastructure.Extensions;
using static Autodesk.AutoCAD.Windows.Window;

namespace XS.Tunnel.Cad.SteelBracing.Component.SteelShotcrete.GrilleComponent
{
    public class GrilleBuild : AbstractSteelShotcrete
    {

        public GrillePointData GrillePointData { get; set; }

         
        /// <summary>
        /// 主筋轮廓坐
        /// </summary>
        public Dictionary<ContourLineType, List<Curve>> ArchRingContour { get; private set; } = new Dictionary<ContourLineType, List<Curve>>();
        public GrilleParameter GrilleParameter { get; private set; }
        public Split3ArcModel MainArc { get; private set; }

        public Split3ArcModel OuterArc { get; private set; }
        public Split3ArcModel InnerArc { get; private set; }
       


        public GrilleBuild(DarkHoleInfo info, IList<ISysPoint> pointData, SteelShotcreteParameter parameter) : base(info, pointData, parameter)
        {
           
        }
        protected override void Initial()
        {
            GrilleParameter = Parameter as GrilleParameter;
           
            MainArc = ArchRing.ArchRingRetract(GrilleParameter.ShrinkSize).GetByDegreeArc(0,180);
            OuterArc = ArchRing.ArchRingRetract(GrilleParameter.WallInterval).GetByDegreeArc(0, 180);
            InnerArc = ArchRing.ArchRingRetract(GrilleParameter.InnerShrinkSize).GetByDegreeArc(0, 180);

            if (GrilleParameter.WallFoot != null)
            {
                GrilleParameter.WallFoot.SteelType = SteelType.WallFoot;
            }
            GrillePointData = new GrillePointData();
        }


        public override void Build()
        {
            var mainSubsectionArc = MainArc.MiddleArc.ArcSplit(GrilleParameter.Subsection);
            var outerSubsectionArc = OuterArc.MiddleArc.ArcSplit(GrilleParameter.Subsection);
            var innerSubsectionArc = InnerArc.MiddleArc.ArcSplit(GrilleParameter.Subsection);

            var arc= SubsectionArc(mainSubsectionArc,outerSubsectionArc,innerSubsectionArc);
            if (arc == null) return;

            SideWallHnadler(arc.Itme1,arc.Itme2);

            GrilleHandler();
        }

        public override void Draw()
        {

            //Drawing(ArchRing.ToEntitys());
            foreach (var curve in GrillePointData.MainRebar)
            {

                foreach (var item in curve.Value)
                {
                    if (curve.Key != ContourLineType.DottedContour)
                    {
                        item.Color = "#ffff00".ToColor();
                        Drawing(item);
                    }
                }
            }
            Drawing(GrillePointData.AngleIronPoint);

            Drawing(GrillePointData.GrillePoint,"#00FF00");

            Drawing(GrillePointData.StirrupCurve);

            Drawing(GrillePointData.URebar, "#3CB371");

        }

        /// <summary>
        /// 边墙处理
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        public void SideWallHnadler(Line start,Line end)
        {
            var outerLeftStartP= OuterArc.EndArc.IntersectPoint(end);
            var outerLeftEndP = OuterArc.EndArc.GetPointAtDist(OuterArc.EndArc.GetLength()-GrilleParameter.WallFoot.GetUnilateral());//
            var newLeftOuterArc = OuterArc.EndArc.Split(outerLeftStartP, outerLeftEndP);


            var innerLeftStartP = InnerArc.EndArc.IntersectPoint(end);
            var innerLeftEndP = InnerArc.EndArc.GetPointAtDist(InnerArc.EndArc.GetLength() - GrilleParameter.WallFoot.GetUnilateral());
            var newLeftInnerArc = InnerArc.EndArc.Split(innerLeftStartP, innerLeftEndP);

            var outerRightEndP = OuterArc.StartArc.IntersectPoint(start);
            var outerRightStartP = OuterArc.StartArc.GetPointAtDist(GrilleParameter.WallFoot.GetUnilateral());
            var newRightOuterArc = OuterArc.StartArc.Split(outerRightStartP, outerRightEndP);

            var innerRightEntP = InnerArc.StartArc.IntersectPoint(start);
            var innerRightStartP = InnerArc.StartArc.GetPointAtDist(GrilleParameter.WallFoot.GetUnilateral());
            var newRightInnerArc = InnerArc.StartArc.Split(innerRightStartP, innerRightEntP);


            GrillePointData.MainRebar[ContourLineType.OuterContour].Add(newLeftOuterArc);
            GrillePointData.MainRebar[ContourLineType.OuterContour].Add(newRightOuterArc);

            GrillePointData.MainRebar[ContourLineType.OuterContour].Add(newLeftInnerArc);
            GrillePointData.MainRebar[ContourLineType.OuterContour].Add(newRightInnerArc);

            var left = new Line(innerLeftEndP, outerLeftEndP);
            var right = new Line(innerRightStartP, outerRightStartP);

            var l = (GrilleParameter.WallFoot.Length - left.Length) / 2;

            var rightL = right.ToBothSidesLengthen(l);
            var leftL = left.ToBothSidesLengthen(l).Reversal() as Line;

            GrillePointData.AngleIronPoint.Add(new SteelPlateComponent(GrilleParameter.WallFoot).CreateWallFoot(rightL));
            GrillePointData.AngleIronPoint.Add(new SteelPlateComponent(GrilleParameter.WallFoot).CreateWallFoot(leftL));

        }


        /// <summary>
        /// 分段
        /// </summary>
        /// <param name="mainArc"></param>
        /// <param name="outerArcs"></param>
        /// <param name="innerArcs"></param>
        /// <returns>返回开始和结束</returns>
        public TupleExt<Line,Line> SubsectionArc(List<Curve> mainArc, List<Curve> outerArcs, List<Curve> innerArcs)
        {

            var angleHeight = GrilleParameter.AngleIron.Height;
            var vtTop = mainArc.GetArcPointVerticalLine(angleHeight / 2);
            var vtBottom = mainArc.GetArcPointVerticalLine(-angleHeight / 2);
            var vtLines = vtTop.BothEndsMerge(vtBottom);

            var newMainArc=new List<Curve>();
            var newOuterArc=new List<Curve>();
            var newInnerArc=new List<Curve>();

            Line startLine = null;
            Line endLine = null;

            // 上一个
            Line lastLeftLine=null;
            for (int i = 0; i < vtLines.Count; i++)
            {
                var vt = vtLines[i];
               
                GrilleParameter.AngleIron.Build(vt);
                GrillePointData.AngleIronPoint.Add(GrilleParameter.AngleIron.RightAngleIron);
                GrillePointData.AngleIronPoint.Add(GrilleParameter.AngleIron.RightThickness);
                GrillePointData.AngleIronPoint.Add(GrilleParameter.AngleIron.LeftAngleIron);
                GrillePointData.AngleIronPoint.Add(GrilleParameter.AngleIron.LeftThickness);


                if (lastLeftLine == null)
                {
                    lastLeftLine = GrilleParameter.AngleIron.LeftAngleIronLine;
                    startLine = GrilleParameter.AngleIron.RightAngleIronLine;
                }
                else
                {

                    var item = mainArc[i - 1 ];
                    var outer = outerArcs[i - 1];
                    var inner = innerArcs[i - 1];

                    var outerStart= outer.IntersectPoint(lastLeftLine, Intersect.OnBothOperands);
                    var outerEnd = outer.IntersectPoint(GrilleParameter.AngleIron.RightAngleIronLine, Intersect.OnBothOperands);

                    var outerArc = outer.Split(outerStart, outerEnd);

                    var innerStart = inner.IntersectPoint(lastLeftLine, Intersect.OnBothOperands);
                    var innerEnd = inner.IntersectPoint(GrilleParameter.AngleIron.RightAngleIronLine, Intersect.OnBothOperands);
                    var innerArc = inner.Split(innerStart, innerEnd);
                    newMainArc.Add(item);
                    newInnerArc.Add(innerArc);
                    newOuterArc.Add(outerArc);
                    lastLeftLine = GrilleParameter.AngleIron.LeftAngleIronLine;
                }
                if (i == vtLines.Count - 1)
                {
                    endLine = GrilleParameter.AngleIron.LeftAngleIronLine;
                }
            }

            GrillePointData.MainRebar.Add( ContourLineType.DottedContour,newMainArc);
            GrillePointData.MainRebar.Add(ContourLineType.InnerContour,newInnerArc);
            GrillePointData.MainRebar.Add(ContourLineType.OuterContour,newOuterArc);

            return TupleExt.Create(startLine,endLine);
        }

      

        /// <summary>
        /// 格栅
        /// </summary>
        public void GrilleHandler()
        {
            URebarHandle();
            if (GrilleParameter.Grille is FigureOfEightGrille)
            {
                FigureOfEightHandle();
            }
            else
            {
                RectangleGrilleHandle();
            }
        }

        /// <summary>
        /// u型筋处理
        /// </summary>
        public void URebarHandle()
        {
            var mains = GrillePointData.MainRebar[ContourLineType.DottedContour];
            foreach (var item in mains)
            { 
                CreateURebar(item);
            }
            CreateSideURebar(MainArc.EndArc, MainArc.StartArc);
        }
        /// <summary>
        /// 边墙的U型筋
        /// </summary>
        /// <param name=""></param>
        public void CreateSideURebar(Curve left, Curve right)
        {
            var uH = GrilleParameter.Grille.URebar.Height;
            //u型筋厚度
            var gH = GrilleParameter.WallFoot.Thickness;
            var ls = left.VerticalLine(left.StartPoint, uH / 2);
            GrillePointData.URebar.AddRange(GrilleParameter.Grille.URebar.AnticlockwiseCreate(ls));

            var re = right.VerticalLine(right.EndPoint, uH / 2);
            GrillePointData.URebar.AddRange(GrilleParameter.Grille.URebar.ClockwiseCreate(re));

            var rs = right.VerticalLine(right.GetPointAtDist(gH), uH / 2);
            var ln = left.VerticalLine(left.GetPointAtDist(right.GetLength() - gH), uH / 2);

            GrillePointData.URebar.AddRange(GrilleParameter.Grille.URebar.AnticlockwiseCreate(rs));
            GrillePointData.URebar.AddRange(GrilleParameter.Grille.URebar.ClockwiseCreate(ln));

        }
        /// <summary>
        /// 创建u型筋
        /// </summary>
        /// <param name="main"></param>
        public void CreateURebar(Curve main)
        {
            var uH = GrilleParameter.Grille.URebar.Height;

            var d = main.VerticalLine(main.EndPoint, uH / 2);
            var u = GrilleParameter.Grille.URebar.ClockwiseCreate(d);
            GrillePointData.URebar.AddRange(u);


            var d1 = main.VerticalLine(main.StartPoint, uH / 2);
            var u1 = GrilleParameter.Grille.URebar.AnticlockwiseCreate(d1);
            GrillePointData.URebar.AddRange(u1);

        }

        /// <summary>
        /// 矩形格栅处理
        /// </summary>
        public void RectangleGrilleHandle()
        {
            var mains = GrillePointData.MainRebar[ContourLineType.DottedContour];
            mains.Add(MainArc.StartArc);
            mains.Add(MainArc.EndArc);
            for (int i = 0; i < mains.Count; i++)
            {
                var main = mains[i];
                CreateRectangleGrille(main);
            }
        }

        /// <summary>
        /// 创建矩形格栅
        /// </summary>
        /// <param name="main"></param>
        public void CreateRectangleGrille(Curve main)
        {
            //u型钢长度
            var uL = GrilleParameter.Grille.URebar.Width;
            // 排除2边u型钢筋
            var arc = main.Split(uL, main.GetLength() - uL);
            var arcL = arc.GetLength();
            // 钢支撑长度
            var gL = GrilleParameter.Grille.Length;
            //钢支撑高度
            var gH = GrilleParameter.Grille.Height;
            // 可以绘制多少个 钢支撑
            var n = Math.Floor(arcL / gL);
            //箍筋间距
            var gjL = GrilleParameter.Grille.Stirrup.Interval;
            bool isBoth = n % 2 == 0;
            Point3d? middlePoint = null;
            if (isBoth)
            {
                // 中心点
                middlePoint = arc.GetPointAtDist(arcL / 2);
            }
            else
            {
                // 中心点相当于中心点
                middlePoint = arc.GetPointAtDist((arcL / 2) + (gL / 2));
            }
            // 分为新的左右圆弧
            var newArc = arc.Split(middlePoint.Value);
            // 左边圆弧
            var leftArc = newArc.Itme2;
            // 右边圆弧
            var rightArc = newArc.Itme1;
            var rlist = rightArc.ClockwiseArcSplit(gjL);
            var llist = leftArc.AnticlockwiseArcSplit(gjL);

            StirrupHandle(rlist, llist);
            SteelSupportHandle(rlist, llist, isBoth);
        }

        /// <summary>
        /// 支撑筋(矩形和三角形)
        /// </summary>
        /// <param name="rList"></param>
        /// <param name="lList"></param>
        /// <param name="isBoth"></param>
        public void SteelSupportHandle(List<Curve> rList, List<Curve> lList, bool isBoth)
        {
            if (isBoth)
            {
                for (int i = rList.Count - 1; i >= 0; i--)
                {
                    var item = rList[i];
                    if (i % 2 == 0)
                    {
                        if (i  <= 0)
                        {
                            break;
                        }

                        Line l = new Line(item.StartPoint, item.EndPoint);
                        var list = GrilleParameter.Grille.Create(l);
                        GrillePointData.GrillePoint.Add(list);
                    }
                }
            }
            else
            {
                for (int i = rList.Count - 2; i >= 0; i--)
                {
                    var item = rList[i];
                    if (i % 2 != 0)
                    {
                        if (i  <= 0)
                        {
                            break;
                        }
                        Line l = new Line(item.StartPoint, item.EndPoint);
                        var list = GrilleParameter.Grille.Create(l);
                        GrillePointData.GrillePoint.Add(list);
                    }
                }
            }


            for (int i = 0; i < lList.Count; i++)
            {
                var item = lList[i];
                if (i % 2 == 0)
                {
                    Line l = new Line(item.StartPoint, item.EndPoint);
                    if (lList.Count - i <= 1)
                    {
                        break;
                    }
                    var list = GrilleParameter.Grille.Create(l);
                    GrillePointData.GrillePoint.Add(list);
                }
            }
        
        }
     
        /// <summary>
        /// 八字节处理
        /// </summary>
        /// <param name="rList"></param>
        /// <param name="lList"></param>
        /// <param name="isBoth"></param>
        public void FigureOfEightHandle()
        {
            var mains = GrillePointData.MainRebar[ContourLineType.DottedContour];
            for (int i = 0; i < mains.Count; i++)
            {
                var main = mains[i];
                CreateFigureOfEight(main);
            }

            var newStarArc= MainArc.StartArc.Split( GrilleParameter.WallFoot.Thickness,true);
            //newStarArc.Color = "#0094ff".ToColor();
            //Drawing(newStarArc);
            CreateFigureOfEight(newStarArc, "start");

            var newEndArc = MainArc.EndArc.Split(MainArc.EndArc.GetLength()-GrilleParameter.WallFoot.Thickness);
            //newEndArc.Color = "#0094ff".ToColor();
            //Drawing(newEndArc);
            CreateFigureOfEight(newEndArc, "end");
        }

        /// <summary>
        /// 创建八字节
        /// </summary>
        /// <param name="curve"></param>
        /// <param name="type"></param>
        public void CreateFigureOfEight(Curve curve,string type="")
        {
            //u型钢长度
            var uL = GrilleParameter.Grille.URebar.Width;
            // 排除2边u型钢筋
            var arc = curve.Split(uL, curve.GetLength() - uL);

            var arcL = arc.GetLength();
            // 钢支撑长度
            var gL = GrilleParameter.Grille.Length;
            //钢支撑高度
            var gH = GrilleParameter.Grille.Height;
            // 可以绘制多少个 钢支撑
            var n = Math.Floor(arcL / gL);
            //箍筋间距
            var gjL = GrilleParameter.Grille.Stirrup.Interval;
            bool isBoth = n % 2 == 0;
            Point3d? middlePoint = null;
            if (isBoth)
            {
                // 中心点
                middlePoint = arc.GetPointAtDist(arcL / 2);
            }
            else
            {
                // 中心点相当于中心点
                middlePoint = arc.GetPointAtDist((arcL / 2) + (gL / 2));
            }
            // 分为新的左右圆弧
            var newArc = arc.Split(middlePoint.Value);
            // 左边圆弧
            var leftArc = newArc.Itme2;
            // 右边圆弧
            var rightArc = newArc.Itme1;

            CreateFigureOfEightOutline(arc,leftArc,rightArc,type);

        }
        /// <summary>
        /// 创建八字节 直线
        /// </summary>
        /// <param name="arc"></param>
        /// <param name="leftArc"></param>
        /// <param name="rightArc"></param>
        /// <param name="type"></param>
        public void CreateFigureOfEightOutline(Curve arc, Curve leftArc,Curve rightArc,string type)
        {
            var arcL = arc.GetLength();
            //箍筋间距
            var gjL = GrilleParameter.Grille.Stirrup.Interval;
            var rlist = rightArc.ClockwiseArcSplit(gjL);
            var llist = leftArc.AnticlockwiseArcSplit(gjL);
            StirrupHandle(rlist, llist);

            for (int i = rlist.Count-1; i >=0; i--)
            {
                var item = rlist[i];
                //var chL = arcL - arc.GetDistAtPoint(item.StartPoint);
                var chL = arc.GetDistAtPoint(item.StartPoint);
                if (chL <= gjL / 2)
                {
                    break;
                }
                var vt = item.GetFirstDerivative(item.StartPoint).GetNormal();
                var point = item.StartPoint;
                Line l = new Line(point.Add(vt * -(GrilleParameter.Grille.Length / 2)), point.Add(vt * (GrilleParameter.Grille.Length / 2)));
                var newLine = new Line(l.EndPoint, l.StartPoint);

                var list = GrilleParameter.Grille.Create(newLine);
                GrillePointData.GrillePoint.Add(list);

            }


            //foreach (var item in rlist)
            //{
            //    //arc.GetDistAtPoint(newLine.EndPoint);

            //    var vt = item.GetFirstDerivative(item.StartPoint).GetNormal();
            //    var point = item.StartPoint;
            //    Line l = new Line(point.Add(vt * -(GrilleParameter.Grille.Length / 2)), point.Add(vt * (GrilleParameter.Grille.Length / 2)));
            //    var newLine = new Line(l.EndPoint, l.StartPoint);
              
            //    var list = GrilleParameter.Grille.Create(newLine);
            //    GrillePointData.GrillePoint.Add(list);
            //}

            foreach (var item in llist)
            {
               

                var vt = item.GetFirstDerivative(item.StartPoint).GetNormal();
                var point = item.StartPoint;
                Line l = new Line(point.Add(vt * -(GrilleParameter.Grille.Length / 2)), point.Add(vt * (GrilleParameter.Grille.Length / 2)));
                var list = GrilleParameter.Grille.Create(l);
                GrillePointData.GrillePoint.Add(list);
            }

          // 
            {
                var last = llist.Last();
                var chL =  arcL- arc.GetDistAtPoint(last.EndPoint);
                if (chL >= gjL / 2)
                {
                    var vt = last.GetFirstDerivative(last.EndPoint).GetNormal();
                    var point = last.EndPoint;
                    Line l = new Line(point.Add(vt * -(GrilleParameter.Grille.Length / 2)), point.Add(vt * (GrilleParameter.Grille.Length / 2)));
                    var list = GrilleParameter.Grille.Create(l);
                    GrillePointData.GrillePoint.Add(list);
                }
              
            }
           // if (type == "end")
            //{
            //    var start = rlist.Last();

            //    var chL =arc.GetDistAtPoint(start.EndPoint);
            //    if (chL >= gjL / 2) {

            //        var vt = start.GetFirstDerivative(start.EndPoint).GetNormal();
            //        var point = start.EndPoint;
            //        Line l = new Line(point.Add(vt * -(GrilleParameter.Grille.Length / 2)), point.Add(vt * (GrilleParameter.Grille.Length / 2)));
            //        var newLine = new Line(l.EndPoint, l.StartPoint);

            //        var list = GrilleParameter.Grille.Create(newLine);
            //        GrillePointData.GrillePoint.Add(list);
            //    }
                 
              
            //}


        }


        /// <summary>
        /// 箍筋 处理
        /// </summary>
        /// <param name="rList"></param>
        /// <param name="lList"></param>
        public void StirrupHandle(List<Curve> rList, List<Curve> lList)
        {

            //箍筋高度
            var gjH = GrilleParameter.Grille.Stirrup.Height;

            for (int i = 0; i < rList.Count; i++)
            {
                var curve = rList[i];
                 GrillePointData.StirrupCurve.Add(curve.ToBothSidesLengthen(curve.EndPoint, gjH / 2));
            }

            for (int i = 1; i < lList.Count; i++)
            {
                var curve = lList[i];
                GrillePointData.StirrupCurve.Add(curve.ToBothSidesLengthen(curve.StartPoint, gjH / 2));
            }

            var Llast = lList.LastOrDefault();
            var Rlast = rList.LastOrDefault();
            GrillePointData.StirrupCurve.Add(Llast.ToBothSidesLengthen(Llast.EndPoint, gjH / 2));
            //GrillePointData.StirrupCurve.Add(Rlast.ToBothSidesLengthen(Rlast.EndPoint, gjH / 2));
        }

    }
}
